home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / BuildingBlocks / OCEObjects.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  40.8 KB  |  1,678 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        OCEObjects.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef __BLJSTANDARDINCLUDES__
  15. #include "BLJStandardIncludes.h"
  16. #endif
  17.  
  18. #ifndef    __OCEOBJECTS__
  19. #include "OCEObjects.h"
  20. #endif
  21.  
  22. #ifndef    __IOSTREAM__
  23. #include "IOStream.h"
  24. #endif
  25.  
  26. #ifndef    __STRING__
  27. #include "String.h"
  28. #endif
  29.  
  30. #ifndef    __SCRIPT__
  31. #include "Script.h"                // for UpperText and LowerText
  32. #endif
  33.  
  34. #ifndef    __FILES__
  35. #include "Files.h"                // for FSWrite & FSRead
  36. #endif
  37.  
  38. #ifndef    __DEBUGASSERT__
  39. #include "DebugAssert.h"        // for ASSERT macros
  40. #endif
  41.  
  42. #ifndef    __NEWDELETE__
  43. #include "NewDelete.h"
  44. #endif
  45.  
  46. #ifndef __THREADUTILITIES__
  47. #include "ThreadUtilities.h"
  48. #endif
  49.  
  50. #ifndef    __ABSTRACTFILE__
  51. #include "AbstractFile.h"
  52. #endif
  53.  
  54. #pragma segment OCEObjects
  55.  
  56. /***********************************|****************************************/
  57.  
  58. // internal validity checking
  59.  
  60. static Boolean gInternalValidityChecking = false;
  61.  
  62. void     SetOCEObjectsInternalValidityChecking ( Boolean state ) { gInternalValidityChecking = state; }
  63. Boolean GetOCEObjectsInternalValidityChecking () { return gInternalValidityChecking; }
  64.  
  65. /***********************************|****************************************/
  66.  
  67. unsigned short
  68. TRString::GetLogicalLength ( const RString* p )
  69. {
  70.     return p ? p->dataLength : 0;
  71. }
  72.  
  73. /***********************************|****************************************/
  74.  
  75. unsigned short
  76. TRString::GetPhysicalSize ( const RString* p )
  77. {
  78.     return GetPhysicalSize ( p ? p->dataLength : 0 );
  79. }
  80.  
  81. /***********************************|****************************************/
  82.  
  83. RString*
  84. TRString::Allocate ( unsigned short logicalLength, CharacterSet script, const void* source )
  85. {
  86.     logicalLength = ( logicalLength < kRStringMaxBytes ) ? logicalLength : kRStringMaxBytes;
  87.     RString* string = (RString*) FAILNewPtrClear ( GetPhysicalSize ( logicalLength ) );
  88.     ASSERT_RETURN_ZERO ( string != nil );
  89.     string->charSet = script;
  90.     string->dataLength = logicalLength;
  91.  
  92.     if ( source )
  93.         ::BlockMove ( source, &string->body, logicalLength );
  94.  
  95.     string->body [ logicalLength ] = '\0'; // add null terminator
  96.  
  97.     return string;
  98. }
  99.  
  100. /***********************************|****************************************/
  101.  
  102. void
  103. TRString::Deallocate ( RString*& p )
  104. {
  105.     if ( p )
  106.     {
  107.         ::DeallocatePtr( (Ptr) p );
  108. #if defined ( INTERNAL_CHECKS )
  109.         ASSERT ( MemError () == noErr );
  110. #endif
  111.         p = nil;
  112.     }
  113. }
  114.  
  115. /***********************************|****************************************/
  116.  
  117. Boolean
  118. TRString::IsValidIndex ( unsigned short i ) const
  119. {
  120.     return ( i >= 0 ) && ( i < fString->dataLength );
  121. }
  122.  
  123. /***********************************|****************************************/
  124.  
  125. unsigned short
  126. TRString::GetLogicalSize ( unsigned short physicalSize )
  127. {
  128.     return physicalSize - GetPhysicalSize ( (unsigned short) 0 );
  129. }
  130.  
  131. /***********************************|****************************************/
  132.  
  133. Boolean
  134. TRString::IsValid ( ConstRStringPtr r, RStringKind k )
  135. {
  136.     return ( r != nil ) && ::OCEValidRString ( r, k );
  137. }
  138.  
  139. /***********************************|****************************************/
  140.  
  141. Boolean
  142. TRString::IsValid () const
  143. {
  144.     return IsValid ( fString, fKind );
  145. }
  146.  
  147. /***********************************|****************************************/
  148.  
  149. Boolean
  150. TRString::IsValid ( const TRString* r )
  151. {
  152.     return r != nil && r->IsValid ();
  153. }
  154.  
  155. /***********************************|****************************************/
  156.  
  157. #if defined ( INTERNAL_CHECKS )
  158.  
  159. Boolean
  160. TRString::IsValidInternal ( const RString* r, RStringKind k )
  161. {
  162.     return !gInternalValidityChecking || IsValid ( r, k );
  163. }
  164.  
  165. #endif
  166.  
  167. /***********************************|****************************************/
  168.  
  169. TRString::TRString ():
  170.     fString ( Allocate ( 0 ) ),
  171.     fKind ( kOCEGenericSensitive )
  172. {
  173. #if defined ( INTERNAL_CHECKS )
  174.     ASSERT ( IsValidInternal () );
  175. #endif
  176. }
  177.  
  178. /***********************************|****************************************/
  179.  
  180. TRString::TRString ( CharacterSet script, RStringKind kind ):
  181.     fString ( Allocate ( 0, script ) ),
  182.     fKind ( kind )
  183. {
  184. #if defined ( INTERNAL_CHECKS )
  185.     ASSERT ( IsValidInternal () );
  186. #endif
  187. }
  188.  
  189. /***********************************|****************************************/
  190.  
  191. TRString::TRString ( const char* source, CharacterSet script, RStringKind kind ):
  192.     fString ( Allocate ( ::strlen ( source ), script, source ) ),
  193.     fKind ( kind )
  194. {
  195. #if defined ( INTERNAL_CHECKS )
  196.     ASSERT ( IsValidInternal () );
  197. #endif
  198. }
  199.  
  200. /***********************************|****************************************/
  201.  
  202. TRString::TRString ( const StringPtr source, CharacterSet script, RStringKind kind ):
  203.     fString ( Allocate ( source [ 0 ], script, source + 1 ) ),
  204.     fKind ( kind )
  205. {
  206. #if defined ( INTERNAL_CHECKS )
  207.     ASSERT ( IsValidInternal () );
  208. #endif
  209. }
  210.  
  211. /***********************************|****************************************/
  212.  
  213. TRString::TRString ( const void* source, unsigned short length, CharacterSet script, RStringKind kind ):
  214.     fString ( Allocate ( length, script, source ) ),
  215.     fKind ( kind )
  216. {
  217. #if defined ( INTERNAL_CHECKS )
  218.     ASSERT ( IsValidInternal () );
  219. #endif
  220. }
  221.  
  222. /***********************************|****************************************/
  223.  
  224. TRString::TRString ( const TRString& string ):
  225.     fString ( Allocate ( string.fString->dataLength, string.fString->charSet, &string.fString->body ) ),
  226.     fKind ( string.fKind )
  227. {
  228. #if defined ( INTERNAL_CHECKS )
  229.     ASSERT ( IsValidInternal () );
  230. #endif
  231. }
  232.  
  233. /***********************************|****************************************/
  234.  
  235. TRString::TRString ( const TRString& string, RStringKind newKind ):
  236.     fString ( Allocate ( string.fString->dataLength, string.fString->charSet, &string.fString->body ) ),
  237.     fKind ( newKind )
  238. {
  239. #if defined ( INTERNAL_CHECKS )
  240.     ASSERT ( IsValidInternal () );
  241. #endif
  242. }
  243.  
  244. /***********************************|****************************************/
  245.  
  246. TRString::TRString ( const RString& string, RStringKind kind ):
  247.     fString ( Allocate ( string.dataLength, string.charSet, &string.body ) ),
  248.     fKind ( kind )
  249. {
  250. #if defined ( INTERNAL_CHECKS )
  251.     ASSERT ( IsValidInternal () );
  252. #endif
  253. }
  254.  
  255. /***********************************|****************************************/
  256.  
  257. TRString::TRString ( const RString* string, RStringKind kind ):
  258.     fString ( string ? Allocate ( GetLogicalLength ( string ), ( (RString*) string )->charSet, &( (RString*) string )->body ) : Allocate ( 0, smRoman ) ),
  259.     fKind ( kind )
  260. {
  261. #if defined ( INTERNAL_CHECKS )
  262.     ASSERT ( IsValidInternal () );
  263. #endif
  264. }
  265.  
  266. /***********************************|****************************************/
  267.  
  268. TRString::~TRString ()
  269. {
  270.     Deallocate ( fString );
  271. }
  272.  
  273. /***********************************|****************************************/
  274.  
  275. TRString&
  276. TRString::operator = ( const TRString& that )
  277. {
  278.     if ( ASSERT ( this != &that ) )
  279.     {
  280.         if ( ASSERT ( that.IsValid () ) )
  281.         {
  282.             Deallocate ( fString );
  283.             fString = Allocate ( that.fString->dataLength, that.fString->charSet, &that.fString->body );
  284. #if defined ( INTERNAL_CHECKS )
  285.             ASSERT ( IsValidInternal () );
  286. #endif
  287.         }
  288.     }
  289.  
  290.     return *this;
  291. }
  292.  
  293. /***********************************|****************************************/
  294.  
  295. TRString&
  296. TRString::operator = ( const RString& string )
  297. {
  298.     if ( ASSERT ( fString != &string ) )
  299.     {
  300.         Deallocate ( fString );
  301.         fString = Allocate ( string.dataLength, string.charSet, &string.body );
  302. #if defined ( INTERNAL_CHECKS )
  303.         ASSERT ( IsValidInternal () );
  304. #endif
  305.     }
  306.  
  307.     return *this;
  308. }
  309.  
  310. /***********************************|****************************************/
  311.  
  312. TRString&
  313. TRString::operator = ( const RString* string )
  314. {
  315.     if ( ASSERT ( string != nil ) )
  316.     {
  317.         operator = ( *string );
  318.     }
  319.     else
  320.     {
  321.         SetLength ( 0 );
  322.     }
  323.  
  324.     return *this;
  325. }
  326.  
  327. /***********************************|****************************************/
  328.  
  329. TRString&
  330. TRString::operator = ( const char* string )
  331. {
  332.     if ( ASSERT ( string != nil ) )
  333.     {
  334.         Deallocate ( fString );
  335.         fString = Allocate ( ::strlen ( string ), smRoman, string );
  336. #if defined ( INTERNAL_CHECKS )
  337.         ASSERT ( IsValidInternal () );
  338. #endif
  339.     }
  340.     else
  341.     {
  342.         SetLength ( 0 );
  343.     }
  344.  
  345.     return *this;
  346. }
  347.  
  348. /***********************************|****************************************/
  349.  
  350. TRString&
  351. TRString::operator = ( const StringPtr string )
  352. {
  353.     if ( ASSERT ( string != nil ) )
  354.     {
  355.         Deallocate ( fString );
  356.         fString = Allocate ( string [ 0 ], smRoman, string + 1 );
  357. #if defined ( INTERNAL_CHECKS )
  358.         ASSERT ( IsValidInternal () );
  359. #endif
  360.     }
  361.     else
  362.     {
  363.         SetLength ( 0 );
  364.     }
  365.  
  366.     return *this;
  367. }
  368.  
  369. /***********************************|****************************************/
  370.  
  371. TRString::operator const RString* () const
  372. {
  373. #if defined ( INTERNAL_CHECKS )
  374.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  375. #endif
  376.     return fString;
  377. }
  378.  
  379. /***********************************|****************************************/
  380.  
  381. TRString::operator const RString& () const
  382. {
  383. #if defined ( INTERNAL_CHECKS )
  384.     ASSERT ( IsValidInternal () );
  385. #endif
  386.     return *fString;
  387. }
  388.  
  389. /***********************************|****************************************/
  390.  
  391. TRString::operator const char* () const
  392. {
  393. #if defined ( INTERNAL_CHECKS )
  394.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  395. #endif
  396.     return (const char*) fString->body;
  397. }
  398.  
  399. /***********************************|****************************************/
  400.  
  401. TRString::operator const StringPtr () const
  402. {
  403. #if defined ( INTERNAL_CHECKS )
  404.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  405. #endif
  406.     return (const StringPtr) &fString->dataLength + sizeof ( fString->dataLength ) - 1;
  407. }
  408.  
  409. /***********************************|****************************************/
  410.  
  411. Byte&
  412. TRString::operator [] ( unsigned short index ) const
  413. {
  414. #if defined ( INTERNAL_CHECKS )
  415.     if ( ASSERT ( IsValidInternal () ) && ASSERT ( IsValidIndex ( index ) ) )
  416. #else
  417.     if ( ASSERT ( IsValidIndex ( index ) ) )
  418. #endif
  419.     {
  420.         return fString->body [ index ];
  421.     }
  422.     else
  423.     {
  424.         static Byte gBozoChar = '\0';
  425.         return gBozoChar;    // let the bozo read from or write to the bozo char
  426.     }
  427. }
  428.  
  429. /***********************************|****************************************/
  430.  
  431. Boolean
  432. TRString::GetString ( RString& destination, unsigned short maxChars ) const
  433. {
  434. #if defined ( INTERNAL_CHECKS )
  435.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  436. #endif
  437.  
  438.     const unsigned short sourceSize = fString->dataLength;
  439.     destination.charSet = fString->charSet;
  440.  
  441.     if ( sourceSize > maxChars )
  442.         destination.dataLength = maxChars;
  443.     else
  444.         destination.dataLength = sourceSize;
  445.  
  446.     ::BlockMove ( fString->body, destination.body, destination.dataLength );
  447.  
  448.     return destination.dataLength == fString->dataLength;
  449. }
  450.  
  451. /***********************************|****************************************/
  452.  
  453. Boolean
  454. TRString::GetString ( StringPtr string, unsigned short maxChars ) const
  455. {
  456. #if defined ( INTERNAL_CHECKS )
  457.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  458. #endif
  459.  
  460.     const unsigned short sourceSize = fString->dataLength;
  461.  
  462.     if ( sourceSize > 0xFF )
  463.         string [ 0 ] = 0xFF;
  464.     else if ( sourceSize > maxChars )
  465.         string [ 0 ] = maxChars;
  466.     else
  467.         string [ 0 ] = (unsigned char) sourceSize;
  468.  
  469.     ::BlockMove ( fString->body, string + 1, string [ 0 ] );
  470.     return string [ 0 ] == fString->dataLength;
  471. }
  472.  
  473. /***********************************|****************************************/
  474.  
  475. Boolean
  476. TRString::GetString ( char* string, unsigned short maxChars ) const
  477. {
  478. #if defined ( INTERNAL_CHECKS )
  479.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  480. #endif
  481.  
  482.     unsigned short sourceSize = fString->dataLength;
  483.  
  484.     if ( sourceSize > maxChars )
  485.         sourceSize = maxChars;
  486.  
  487.     ::BlockMove ( fString->body, string, sourceSize );
  488.     return sourceSize == fString->dataLength;
  489. }
  490.  
  491. /***********************************|****************************************/
  492.  
  493. RString*
  494. TRString::GetNewRString () const
  495. {
  496. #if defined ( INTERNAL_CHECKS )
  497.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  498. #endif
  499.     return Allocate ( fString->dataLength, fString->charSet, &fString->body );
  500. }
  501.  
  502. /***********************************|****************************************/
  503.  
  504. StringPtr
  505. TRString::GetNewStringPtr () const
  506. {
  507. #if defined ( INTERNAL_CHECKS )
  508.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  509. #endif
  510.  
  511.     unsigned short sourceSize = fString->dataLength;
  512.  
  513.     if ( sourceSize > 0xFF )    // make sure that we don’t overflow
  514.         sourceSize = 0xFF;
  515.  
  516.     StringPtr string = (StringPtr) FAILNewPtrClear ( sourceSize + 2 );    // extra bytes are prefix length byte and null terminator
  517.     ASSERT_RETURN_ZERO ( string != nil );
  518.  
  519.     ::BlockMove ( &fString->body, string, sourceSize );
  520.     string [ 0 ] = sourceSize;        // fill in prefix length byte
  521.     string [ sourceSize + 1 ] = 0;    // fill in null terminator
  522.  
  523.     return string;
  524. }
  525.  
  526. /***********************************|****************************************/
  527.  
  528. char*
  529. TRString::GetNewString () const
  530. {
  531. #if defined ( INTERNAL_CHECKS )
  532.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  533. #endif
  534.  
  535.     const unsigned short sourceSize = fString->dataLength + 1; // extra byte is null terminator
  536.  
  537.     char* string = (char*) FAILNewPtrClear ( sourceSize );
  538.     ASSERT_RETURN_ZERO ( string != nil );
  539.  
  540.     ::BlockMove ( &fString->body, string, sourceSize );
  541.  
  542.     return string;
  543. }
  544.  
  545. /***********************************|****************************************/
  546.  
  547. unsigned short
  548. TRString::SetLength ( unsigned short newSize )
  549. {
  550. #if defined ( INTERNAL_CHECKS )
  551.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  552. #endif
  553.  
  554.     RString* newString = Allocate ( newSize, fString->charSet, &fString->body );
  555.  
  556.     if ( newString )
  557.     {
  558.         Deallocate ( fString );
  559.         fString = newString;
  560.         return newSize;
  561.     }
  562.     else
  563.     {
  564.         return fString->dataLength;
  565.     }
  566. }
  567.  
  568. /***********************************|****************************************/
  569.  
  570. void
  571. TRString::SetScript ( CharacterSet c )
  572. {
  573. #if defined ( INTERNAL_CHECKS )
  574.     ASSERT_RETURN ( IsValidInternal () );
  575. #endif
  576.     fString->charSet = c;
  577. }
  578.  
  579. /***********************************|****************************************/
  580.  
  581. void
  582. TRString::SetKind ( RStringKind kind )
  583. {
  584. #if defined ( INTERNAL_CHECKS )
  585.     ASSERT_RETURN ( IsValidInternal () );
  586. #endif
  587.     fKind = kind;
  588. }
  589.  
  590. /***********************************|****************************************/
  591.  
  592. void
  593. TRString::MakeUppercase ()
  594. {
  595. #if defined ( INTERNAL_CHECKS )
  596.     ASSERT_RETURN ( IsValidInternal () );
  597. #endif
  598.     ::UpperText ( (Ptr) &fString->body, fString->dataLength );
  599. }
  600.  
  601. /***********************************|****************************************/
  602.  
  603. void
  604. TRString::MakeLowercase ()
  605. {
  606. #if defined ( INTERNAL_CHECKS )
  607.     ASSERT_RETURN ( IsValidInternal () );
  608. #endif
  609.     ::LowerText ( (Ptr) &fString->body, fString->dataLength );
  610. }
  611.  
  612. /***********************************|****************************************/
  613.  
  614. long
  615. TRString::Compare ( const RString& string ) const
  616. {
  617.     return ::OCERelRString ( fString, &string, fKind );
  618. }
  619.  
  620. /***********************************|****************************************/
  621.  
  622. long
  623. TRString::Compare ( const TRString& string ) const
  624. {
  625.     return ::OCERelRString ( fString, string.fString, fKind );
  626. }
  627.  
  628. /***********************************|****************************************/
  629.  
  630. long
  631. TRString::Compare ( const char* string ) const
  632. {
  633. #if defined ( INTERNAL_CHECKS )
  634.     ASSERT ( IsValidInternal () );
  635. #endif
  636.     return ::strcmp ( *this, string );
  637. }
  638.  
  639. /***********************************|****************************************/
  640.  
  641. long
  642. TRString::Compare ( const StringPtr string ) const
  643. {
  644. #if defined ( INTERNAL_CHECKS )
  645.     ASSERT ( IsValidInternal () );
  646. #endif
  647.     return ::RelString ( *this, string, true, true );
  648. }
  649.  
  650. /***********************************|****************************************/
  651.  
  652. ostream&
  653. TRString::operator >> ( ostream& s ) const
  654. {
  655. #if defined ( INTERNAL_CHECKS )
  656.     ASSERT ( IsValidInternal () );
  657. #endif
  658.     s << "["; s.write ( fString->body, fString->dataLength );
  659.     if ( fString->charSet != smRoman )
  660.         s << ", " << fString->charSet;
  661.     s << "]";
  662.     return s;
  663. }
  664.  
  665. /***********************************|****************************************/
  666.  
  667. Boolean
  668. TRString::Write ( TAbstractFile& f ) const
  669. {
  670. #if defined ( INTERNAL_CHECKS )
  671.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  672. #endif
  673.     unsigned short physicalSize = GetPhysicalSize ( fString );
  674.     ASSERT_RETURN_ZERO ( f.Write ( physicalSize ) == noErr );
  675.     ASSERT_RETURN_ZERO ( f.WriteDataIgnore ( fString, physicalSize ) == noErr );
  676.     ASSERT_RETURN_ZERO ( f.Write ( fKind ) == noErr );
  677.     return true;
  678. }
  679.  
  680. /***********************************|****************************************/
  681.  
  682. Boolean
  683. TRString::Read ( TAbstractFile& f )
  684. {
  685.     unsigned short physicalSize = 0;
  686.     ASSERT_RETURN_ZERO ( f.Read ( physicalSize ) == noErr );
  687.     ASSERT_RETURN_ZERO ( physicalSize >= GetPhysicalSize ( (unsigned short) 0 ) );
  688.     RString* temp = Allocate ( GetLogicalSize ( physicalSize ) );
  689.     ASSERT_RETURN_ZERO ( temp != nil );
  690.     ASSERT_RETURN_ZERO ( f.ReadDataIgnore ( temp, physicalSize ) == noErr );
  691.     Deallocate ( fString );
  692.     fString = temp;
  693.     ASSERT_RETURN_ZERO ( f.Read ( fKind ) == noErr );
  694. #if defined ( INTERNAL_CHECKS )
  695.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  696. #endif
  697.     return true;
  698. }
  699.  
  700. /***********************************|****************************************/
  701. /***********************************|****************************************/
  702.  
  703. TDirectoryName::TDirectoryName ( CharacterSet script ):
  704.     TRString ( script, kOCEDirName )
  705. {
  706. }
  707.  
  708. /***********************************|****************************************/
  709.  
  710. TDirectoryName::TDirectoryName ( const char* source, CharacterSet script ):
  711.     TRString ( source, script, kOCEDirName )
  712. {
  713. }
  714.  
  715. /***********************************|****************************************/
  716.  
  717. TDirectoryName::TDirectoryName ( const StringPtr source, CharacterSet script ):
  718.     TRString ( source, script, kOCEDirName )
  719. {
  720. }
  721.  
  722. /***********************************|****************************************/
  723.  
  724. TDirectoryName::TDirectoryName ( const void* source, unsigned short length, CharacterSet script ):
  725.     TRString ( source, length, script, kOCEDirName )
  726. {
  727. }
  728.  
  729. /***********************************|****************************************/
  730.  
  731. TDirectoryName::TDirectoryName ( const TDirectoryName& string ):
  732.     TRString ( string, kOCEDirName )
  733. {
  734. }
  735.  
  736. /***********************************|****************************************/
  737.  
  738. TDirectoryName::TDirectoryName ( const DirectoryName& name ):
  739.     TRString ( (const RString&) name, kOCEDirName )
  740. {
  741. }
  742.  
  743. /***********************************|****************************************/
  744.  
  745. TDirectoryName::TDirectoryName ( const DirectoryName* name ):
  746.     TRString ( (const RString*) name, kOCEDirName )
  747. {
  748. }
  749.  
  750. /***********************************|****************************************/
  751.  
  752. TDirectoryName::TDirectoryName ( const TRString& string ):
  753.     TRString ( string, kOCEDirName )
  754. {
  755. }
  756.  
  757. /***********************************|****************************************/
  758.  
  759. TDirectoryName::TDirectoryName ( const RString& string ):
  760.     TRString ( string, kOCEDirName )
  761. {
  762. }
  763.  
  764. /***********************************|****************************************/
  765.  
  766. TDirectoryName::TDirectoryName ( const RString* string ):
  767.     TRString ( string, kOCEDirName )
  768. {
  769. }
  770.  
  771. /***********************************|****************************************/
  772.  
  773. TDirectoryName::~TDirectoryName ()
  774. {
  775. }
  776.  
  777. /***********************************|****************************************/
  778. /***********************************|****************************************/
  779.  
  780. TCreationID::TCreationID ()
  781. {
  782.     fID.source = fID.seq = 0;
  783. }
  784.  
  785. /***********************************|****************************************/
  786.  
  787. TCreationID::TCreationID ( unsigned long a, unsigned long b )
  788. {
  789.     fID.source = a;
  790.     fID.seq = b;
  791. }
  792.  
  793. /***********************************|****************************************/
  794.  
  795. TCreationID::TCreationID ( const TCreationID& that ):
  796.     fID ( that.fID )
  797. {
  798. }
  799.  
  800. /***********************************|****************************************/
  801.  
  802. TCreationID::TCreationID ( const CreationID& that ):
  803.     fID ( that )
  804. {
  805. }
  806.  
  807. /***********************************|****************************************/
  808.  
  809. TCreationID::TCreationID ( const CreationID* that )
  810. {
  811.     if ( that )
  812.     {
  813.         fID = *that;
  814.     }
  815.     else
  816.     {
  817.         fID.source = 0;
  818.         fID.seq = 0;
  819.     }
  820. }
  821.  
  822. /***********************************|****************************************/
  823.  
  824. TCreationID::~TCreationID ()
  825. {
  826. }
  827.  
  828. /***********************************|****************************************/
  829.  
  830. TCreationID&
  831. TCreationID::operator = ( const TCreationID& that )
  832. {
  833.     if ( ASSERT ( this != &that ) )
  834.     {
  835.         fID = that.fID;
  836.     }
  837.  
  838.     return *this;
  839. }
  840.  
  841. /***********************************|****************************************/
  842.  
  843. TCreationID&
  844. TCreationID::operator = ( const CreationID& that )
  845. {
  846.     fID = that;
  847.     return *this;
  848. }
  849.  
  850. /***********************************|****************************************/
  851.  
  852. Boolean
  853. TCreationID::operator == ( const CreationID& that ) const
  854. {
  855.     return
  856.         fID.source == that.source &&
  857.         fID.seq == that.seq;
  858. }
  859.  
  860. /***********************************|****************************************/
  861.  
  862. Boolean
  863. TCreationID::IsNull () const
  864. {
  865.     return
  866.         fID.source == 0 &&
  867.         fID.seq == 0;
  868. }
  869.  
  870. /***********************************|****************************************/
  871.  
  872. void
  873. TCreationID::GetID ( CreationID& id ) const
  874. {
  875.     id = fID;
  876. }
  877.  
  878. /***********************************|****************************************/
  879.  
  880. void
  881. TCreationID::GetID ( unsigned long& a, unsigned long& b ) const
  882. {
  883.     a = fID.source;
  884.     b = fID.seq;
  885. }
  886.  
  887. /***********************************|****************************************/
  888.  
  889. Boolean
  890. TCreationID::Read ( TAbstractFile& f )
  891. {
  892.     return f.ReadDataIgnore ( &fID, sizeof ( fID ) ) == noErr;
  893. }
  894.  
  895. /***********************************|****************************************/
  896.  
  897. Boolean
  898. TCreationID::Write ( TAbstractFile& f ) const
  899. {
  900.     return f.WriteDataIgnore ( &((TCreationID*) this)->fID, sizeof ( fID ) ) == noErr;
  901. }
  902.  
  903. /***********************************|****************************************/
  904.  
  905. ostream&
  906. TCreationID::operator >> ( ostream& s ) const
  907. {
  908.     return s << fID.source << ':' << fID.seq;
  909. }
  910.  
  911. /***********************************|****************************************/
  912. /***********************************|****************************************/
  913.  
  914. TDirDiscriminator::TDirDiscriminator ()
  915. {
  916.     fDiscriminator.signature = 0;
  917.     fDiscriminator.misc = 0;
  918. }
  919.  
  920. /***********************************|****************************************/
  921.  
  922. TDirDiscriminator::TDirDiscriminator ( OCEDirectoryKind signature, unsigned long misc )
  923. {
  924.     fDiscriminator.signature = signature;
  925.     fDiscriminator.misc = misc;
  926. }
  927.  
  928. /***********************************|****************************************/
  929.  
  930. TDirDiscriminator::TDirDiscriminator ( const TDirDiscriminator& that ):
  931.     fDiscriminator ( that.fDiscriminator )
  932. {
  933. }
  934.  
  935. /***********************************|****************************************/
  936.  
  937. TDirDiscriminator::TDirDiscriminator ( const DirDiscriminator& discriminator ):
  938.     fDiscriminator ( discriminator )
  939. {
  940. }
  941.  
  942. /***********************************|****************************************/
  943.  
  944. TDirDiscriminator::TDirDiscriminator ( const DirDiscriminator* discriminator )
  945. {
  946.     if ( discriminator )
  947.     {
  948.         fDiscriminator = *discriminator;
  949.     }
  950.     else
  951.     {
  952.         fDiscriminator.signature = 0;
  953.         fDiscriminator.misc = 0;
  954.     }
  955. }
  956.  
  957. /***********************************|****************************************/
  958.  
  959. TDirDiscriminator::~TDirDiscriminator ()
  960. {
  961. }
  962.  
  963. /***********************************|****************************************/
  964.  
  965. TDirDiscriminator&
  966. TDirDiscriminator::operator = ( const TDirDiscriminator& that )
  967. {
  968.     if ( ASSERT ( this != &that ) )
  969.     {
  970.         fDiscriminator = that.fDiscriminator;
  971.     }
  972.  
  973.     return *this;
  974. }
  975.  
  976. /***********************************|****************************************/
  977.  
  978. TDirDiscriminator&
  979. TDirDiscriminator::operator = ( const DirDiscriminator& discriminator )
  980. {
  981.     fDiscriminator = discriminator;
  982.     return *this;
  983. }
  984.  
  985. /***********************************|****************************************/
  986.  
  987. TDirDiscriminator&
  988. TDirDiscriminator::operator = ( const DirDiscriminator* discriminator )
  989. {
  990.     if ( discriminator )
  991.     {
  992.         fDiscriminator = *discriminator;
  993.     }
  994.     else
  995.     {
  996.         fDiscriminator.signature = 0;
  997.         fDiscriminator.misc = 0;
  998.     }
  999.  
  1000.     return *this;
  1001. }
  1002.  
  1003. /***********************************|****************************************/
  1004.  
  1005. TDirDiscriminator&
  1006. TDirDiscriminator::operator = ( const OCEDirectoryKind& that )
  1007. {
  1008.     fDiscriminator.signature = that;
  1009.     return *this;
  1010. }
  1011.  
  1012. /***********************************|****************************************/
  1013.  
  1014. Boolean
  1015. TDirDiscriminator::operator == ( const DirDiscriminator& that ) const
  1016. {
  1017.     return
  1018.         fDiscriminator.signature == that.signature &&
  1019.         fDiscriminator.misc == that.misc;
  1020. }
  1021.  
  1022. /***********************************|****************************************/
  1023.  
  1024. void
  1025. TDirDiscriminator::GetDiscriminator ( DirDiscriminator& discriminator ) const
  1026. {
  1027.     discriminator = fDiscriminator;
  1028. }
  1029.  
  1030. /***********************************|****************************************/
  1031.  
  1032. void
  1033. TDirDiscriminator::GetDiscriminator ( OCEDirectoryKind& signature, unsigned long& misc ) const
  1034. {
  1035.     signature = fDiscriminator.signature;
  1036.     misc = fDiscriminator.misc;
  1037. }
  1038.  
  1039. /***********************************|****************************************/
  1040.  
  1041. Boolean
  1042. TDirDiscriminator::Read ( TAbstractFile& f )
  1043. {
  1044.     return f.ReadDataIgnore ( &fDiscriminator, sizeof ( fDiscriminator ) ) == noErr;
  1045. }
  1046.  
  1047. /***********************************|****************************************/
  1048.  
  1049. Boolean
  1050. TDirDiscriminator::Write ( TAbstractFile& f ) const
  1051. {
  1052.     return f.WriteDataIgnore ( &((TDirDiscriminator*)this)->fDiscriminator, sizeof ( fDiscriminator ) ) == noErr;
  1053. }
  1054.  
  1055. /***********************************|****************************************/
  1056.  
  1057. ostream&
  1058. TDirDiscriminator::operator >> ( ostream& s ) const
  1059. {
  1060.     return s << fDiscriminator.signature << ':' << fDiscriminator.misc;
  1061. }
  1062.  
  1063. /***********************************|****************************************/
  1064. /***********************************|****************************************/
  1065.  
  1066. TDirectory::TDirectory ():
  1067.     fName (),
  1068.     fDiscriminator ()
  1069. {
  1070. }
  1071.  
  1072. /***********************************|****************************************/
  1073.  
  1074. TDirectory::TDirectory ( const TDirectoryName& name ):
  1075.     fName ( name ),
  1076.     fDiscriminator ()
  1077. {
  1078. }
  1079.  
  1080. /***********************************|****************************************/
  1081.  
  1082. TDirectory::TDirectory ( const TDirectoryName& name, const TDirDiscriminator& discriminator ):
  1083.     fName ( name ),
  1084.     fDiscriminator ( discriminator )
  1085. {
  1086. }
  1087.  
  1088. /***********************************|****************************************/
  1089.  
  1090. TDirectory::TDirectory ( const TDirectory& that ):
  1091.     fName ( that.fName ),
  1092.     fDiscriminator ( that.fDiscriminator )
  1093. {
  1094. }
  1095.  
  1096. /***********************************|****************************************/
  1097.  
  1098. TDirectory::TDirectory ( const DirectoryName* directory, DirDiscriminator* discriminator ):
  1099.     fName ( directory ),
  1100.     fDiscriminator ( discriminator )
  1101. {
  1102. }
  1103.  
  1104. /***********************************|****************************************/
  1105.  
  1106. TDirectory::~TDirectory ()
  1107. {
  1108. }
  1109.  
  1110. /***********************************|****************************************/
  1111.  
  1112. TDirectory&
  1113. TDirectory::operator = ( const TDirectory& that )
  1114. {
  1115.     if ( ASSERT ( this != &that ) )
  1116.     {
  1117.         fName = that.fName;
  1118.         fDiscriminator = that.fDiscriminator;
  1119.     }
  1120.  
  1121.     return *this;
  1122. }
  1123.  
  1124. /***********************************|****************************************/
  1125.  
  1126. Boolean
  1127. TDirectory::operator == ( const TDirectory& that ) const
  1128. {
  1129.     return
  1130.         fName == that.fName &&
  1131.         fDiscriminator == that.fDiscriminator;
  1132. }
  1133.  
  1134. /***********************************|****************************************/
  1135.  
  1136. void
  1137. TDirectory::SetName ( const TDirectoryName& name )
  1138. {
  1139.     fName = name;
  1140. }
  1141.  
  1142. /***********************************|****************************************/
  1143.  
  1144. Boolean
  1145. TDirectory::GetName ( TDirectoryName& name ) const
  1146. {
  1147.     name = fName;
  1148.     return true;
  1149. }
  1150.  
  1151. /***********************************|****************************************/
  1152.  
  1153. void
  1154. TDirectory::SetDiscriminator ( const TDirDiscriminator& discriminator )
  1155. {
  1156.     fDiscriminator = discriminator;
  1157. }
  1158.  
  1159. /***********************************|****************************************/
  1160.  
  1161. Boolean
  1162. TDirectory::GetDiscriminator ( TDirDiscriminator& discriminator ) const
  1163. {
  1164.     discriminator = fDiscriminator;
  1165.     return true;
  1166. }
  1167.  
  1168. /***********************************|****************************************/
  1169.  
  1170. Boolean
  1171. TDirectory::Read ( TAbstractFile& f )
  1172. {
  1173.     return fName.Read ( f ) && fDiscriminator.Read ( f );
  1174. }
  1175.  
  1176. /***********************************|****************************************/
  1177.  
  1178. Boolean
  1179. TDirectory::Write ( TAbstractFile& f ) const
  1180. {
  1181.     return fName.Write ( f ) && fDiscriminator.Write ( f );
  1182. }
  1183.  
  1184. /***********************************|****************************************/
  1185.  
  1186. ostream&
  1187. TDirectory::operator >> ( ostream& s ) const
  1188. {
  1189.     return s << fName << " (" << fDiscriminator << ')';
  1190. }
  1191.  
  1192. /***********************************|****************************************/
  1193. /***********************************|****************************************/
  1194.  
  1195. PackedPathName*
  1196. TPathName::Allocate ( unsigned short bytes )
  1197. {
  1198.     return (PackedPathName*) FAILNewPtrClear ( bytes );
  1199. }
  1200.  
  1201. /***********************************|****************************************/
  1202.  
  1203. PackedPathName*
  1204. TPathName::Allocate ( const PackedPathName* p1 )
  1205. {
  1206. #if defined ( INTERNAL_CHECKS )
  1207.     ASSERT ( IsValidInternal ( p1 ) );
  1208. #endif
  1209.     unsigned short size = GetPhysicalSize ( p1 );
  1210.     PackedPathName* p2 = Allocate ( size );
  1211.     ASSERT_RETURN_ZERO ( p2 != nil );
  1212. #if defined ( INTERNAL_CHECKS )
  1213.     ASSERT ( ::OCECopyPackedPathName ( p1, p2, size ) == noErr );
  1214. #else
  1215.     ::OCECopyPackedPathName ( p1, p2, size );
  1216. #endif
  1217.     return p2;
  1218. }
  1219.  
  1220. /***********************************|****************************************/
  1221.  
  1222. PackedPathName*
  1223. TPathName::Allocate ( RStringPtr stringArray[], unsigned short entries )
  1224. {
  1225. #if defined ( INTERNAL_CHECKS )
  1226.     ASSERT_RETURN_ZERO ( entries > 0 );
  1227.     ASSERT_RETURN_ZERO ( stringArray != nil );
  1228.     for ( unsigned short jndex = 0; jndex < entries; jndex++ )
  1229.         ASSERT_RETURN_ZERO ( TRString::IsValid ( stringArray [ jndex ], kOCEGenericSensitive ) );
  1230. #endif
  1231.     unsigned short pathNameSize = ::OCEPackedPathNameSize ( stringArray,  entries );
  1232. #if defined ( INTERNAL_CHECKS )
  1233.     ASSERT_RETURN_ZERO ( pathNameSize >= sizeof ( ProtoPackedPathName ) );
  1234. #endif
  1235.     PackedPathName* pathName = (PackedPathName*) Allocate ( pathNameSize );
  1236.     ASSERT_RETURN_ZERO ( pathName != nil );
  1237. #if defined ( INTERNAL_CHECKS )
  1238.     ASSERT_RETURN_ZERO ( ::OCEPackPathName ( stringArray, entries, pathName, pathNameSize ) == noErr );
  1239. #else
  1240.     ::OCEPackPathName ( (const RStringPtr []) stringArray, entries, pathName, pathNameSize );
  1241. #endif
  1242.     return pathName;
  1243. }
  1244.  
  1245. /***********************************|****************************************/
  1246.  
  1247. ConstRStringPtr*
  1248. TPathName::AllocateArray ( const TRString* objectArray [], unsigned short entries )
  1249. {
  1250. #if defined ( INTERNAL_CHECKS )
  1251.     ASSERT_RETURN_ZERO ( entries > 0 );
  1252.     ASSERT_RETURN_ZERO ( objectArray != nil );
  1253.     for ( unsigned short jndex = 0; jndex < entries; jndex++ )
  1254.         ASSERT_RETURN_ZERO ( TRString::IsValid ( objectArray [ jndex ] ) );
  1255. #endif
  1256.     ConstRStringPtr* stringArray = (ConstRStringPtr*) FAILNewPtrClear ( entries * sizeof ( ConstRStringPtr ) );
  1257.     ASSERT_RETURN_ZERO ( stringArray != nil );
  1258.     for ( unsigned short index = 0; index < entries; index++ )
  1259.         stringArray [ index ] = *objectArray [ index ];
  1260.     return stringArray;
  1261. }
  1262.  
  1263. /***********************************|****************************************/
  1264.  
  1265. ConstRStringPtr*
  1266. TPathName::AllocateArray ( const PackedPathName* packed )
  1267. {
  1268. #if defined ( INTERNAL_CHECKS )
  1269.     ASSERT_RETURN_ZERO ( IsValidInternal ( packed ) );
  1270. #endif
  1271.     unsigned short entries = (packed && (packed->dataLength > 0) && 
  1272.                 OCEValidPackedPathName(packed) ) ? ::OCEDNodeNameCount ( packed ) : 0;
  1273.     ConstRStringPtr stringArray = (ConstRStringPtr) FAILNewPtrClear ( entries * sizeof ( ConstRStringPtr ) );
  1274.     ASSERT_RETURN_ZERO ( stringArray != nil );
  1275.     if (entries > 0)
  1276.         ASSERT_RETURN_ZERO ( ::OCEUnpackPathName ( packed, * ( RStringPtr * *) & stringArray, entries ) == entries );
  1277.     return * ( ConstRStringPtr ** ) &stringArray;
  1278. }
  1279.  
  1280. /***********************************|****************************************/
  1281.  
  1282. PackedPathName*
  1283. TPathName::Allocate ( const TRString* objectArray [], unsigned short entries )
  1284. {
  1285.     const RString ** stringArray = AllocateArray ( objectArray, entries );
  1286.     ASSERT_RETURN_ZERO ( stringArray != nil );
  1287.     PackedPathName* pathName = Allocate ( * ( RStringPtr * *) &stringArray, entries );
  1288.     ::DeallocatePtr( (Ptr) stringArray );
  1289.     return pathName;
  1290. }
  1291.  
  1292. /***********************************|****************************************/
  1293.  
  1294. void
  1295. TPathName::Deallocate ( PackedPathName*& p )
  1296. {
  1297.     if ( p )
  1298.     {
  1299.         ::DeallocatePtr( (Ptr) p );
  1300. #if defined ( INTERNAL_CHECKS )
  1301.         ASSERT ( MemError () == noErr );
  1302. #endif
  1303.         p = nil;
  1304.     }
  1305. }
  1306.  
  1307. /***********************************|****************************************/
  1308.  
  1309. void
  1310. TPathName::Deallocate ()
  1311. {
  1312.     InvalidateCache ();
  1313.     Deallocate ( fPacked );
  1314. }
  1315.  
  1316. /***********************************|****************************************/
  1317.  
  1318. void
  1319. TPathName::ValidateCache () const
  1320. {
  1321. #if defined ( INTERNAL_CHECKS )
  1322.     ASSERT_RETURN ( IsValidInternal () );
  1323. #endif
  1324.  
  1325.     if ( !fCache )
  1326.     {
  1327.         ( (TPathName*) this )->fCache = AllocateArray ( fPacked );
  1328. #if defined ( INTERNAL_CHECKS )
  1329.         ASSERT ( fCache != nil );
  1330. #endif
  1331.     }
  1332. }
  1333.  
  1334. /***********************************|****************************************/
  1335.  
  1336. void
  1337. TPathName::InvalidateCache () const
  1338. {
  1339.     if ( fCache )
  1340.     {
  1341.         ::DeallocatePtr( (Ptr) ( (TPathName*) this )->fCache );
  1342. #if defined ( INTERNAL_CHECKS )
  1343.         ASSERT ( MemError () == noErr );
  1344. #endif
  1345.         ( (TPathName*) this )->fCache = nil;
  1346.     }
  1347. }
  1348.  
  1349. /***********************************|****************************************/
  1350.  
  1351. Boolean
  1352. TPathName::IsValidIndex ( unsigned short i ) const
  1353. {
  1354.     return i >= 1 && i <= GetNodeCount ();
  1355. }
  1356.  
  1357. /***********************************|****************************************/
  1358.  
  1359. unsigned short TPathName::GetNodeCount () const 
  1360. {
  1361.     if (fPacked && (fPacked->dataLength > 0))
  1362.         return ::OCEDNodeNameCount ( fPacked ); 
  1363.     return 0;
  1364. }
  1365.  
  1366. /***********************************|****************************************/
  1367.  
  1368. unsigned short
  1369. TPathName::GetPhysicalSize ( const PackedPathName* p )
  1370. {
  1371.     return ( p ? p->dataLength : 0 ) + sizeof ( ProtoPackedPathName );
  1372. }
  1373.  
  1374. /***********************************|****************************************/
  1375.  
  1376. Boolean
  1377. TPathName::IsValid ( const PackedPathName* p )
  1378. {
  1379.     return ( p != nil ) && ::OCEValidPackedPathName ( p );
  1380. }
  1381.  
  1382. /***********************************|****************************************/
  1383.  
  1384. #if defined ( INTERNAL_CHECKS )
  1385.  
  1386. Boolean
  1387. TPathName::IsValidInternal ( const PackedPathName* p )
  1388. {
  1389.     return !gInternalValidityChecking || IsValid ( p );
  1390. }
  1391.  
  1392. #endif
  1393.  
  1394. /***********************************|****************************************/
  1395.  
  1396. TPathName::TPathName ():
  1397.     fPacked ( Allocate ( sizeof ( ProtoPackedPathName ) ) ),
  1398.     fCache ( nil )
  1399. {
  1400. //     ASSERT ( IsValidInternal () );    // we are not valid at this time
  1401. }
  1402.  
  1403. pascal char* GetA6 () = 0x2E8E;
  1404.  
  1405. #define    MAKE_FIRST_PARAM_INTO_TRSTRING_ARRAY() (const TRString**) ( GetA6 () + 0xC )
  1406.  
  1407. /***********************************|****************************************/
  1408.  
  1409. TPathName::TPathName ( const TRString& /* r1 */ ):
  1410.     fPacked ( Allocate ( MAKE_FIRST_PARAM_INTO_TRSTRING_ARRAY (), 1 ) ),
  1411.     fCache ( nil )
  1412. {
  1413. #if defined ( INTERNAL_CHECKS )
  1414.     ASSERT ( IsValidInternal () );
  1415. #endif
  1416. }
  1417.  
  1418. /***********************************|****************************************/
  1419.  
  1420. TPathName::TPathName ( const TRString& /* r1 */, const TRString& ):
  1421.     fPacked ( Allocate ( MAKE_FIRST_PARAM_INTO_TRSTRING_ARRAY (), 2 ) ),
  1422.     fCache ( nil )
  1423. {
  1424. #if defined ( INTERNAL_CHECKS )
  1425.     ASSERT ( IsValidInternal () );
  1426. #endif
  1427. }
  1428.  
  1429. /***********************************|****************************************/
  1430.  
  1431. TPathName::TPathName ( const TRString& /* r1 */, const TRString&, const TRString& ):
  1432.     fPacked ( Allocate ( MAKE_FIRST_PARAM_INTO_TRSTRING_ARRAY (), 3 ) ),
  1433.     fCache ( nil )
  1434. {
  1435. #if defined ( INTERNAL_CHECKS )
  1436.     ASSERT ( IsValidInternal () );
  1437. #endif
  1438. }
  1439.  
  1440. /***********************************|****************************************/
  1441.  
  1442. TPathName::TPathName ( const TPathName& that ):
  1443.     fPacked ( Allocate ( that.fPacked ) ),
  1444.     fCache ( nil )
  1445. {
  1446. #if defined ( INTERNAL_CHECKS )
  1447.     ASSERT ( IsValidInternal () );
  1448. #endif
  1449. }
  1450.  
  1451. /***********************************|****************************************/
  1452.  
  1453. TPathName::TPathName ( const PackedPathName& p ):
  1454.     fPacked ( Allocate ( &p ) ),
  1455.     fCache ( nil )
  1456. {
  1457. #if defined ( INTERNAL_CHECKS )
  1458.     ASSERT ( IsValidInternal () );
  1459. #endif
  1460. }
  1461.  
  1462. /***********************************|****************************************/
  1463.  
  1464. TPathName::TPathName ( const PackedPathName* p ):
  1465.     fPacked ( Allocate ( p ) ),
  1466.     fCache ( nil )
  1467. {
  1468. #if defined ( INTERNAL_CHECKS )
  1469.     ASSERT ( IsValidInternal () );
  1470. #endif
  1471. }
  1472.  
  1473. /***********************************|****************************************/
  1474.  
  1475. TPathName::TPathName ( const RStringPtr * array, unsigned short count ):
  1476.     fPacked ( Allocate ( (RStringPtr *) array, count ) ),
  1477.     fCache ( nil )
  1478. {
  1479. #if defined ( INTERNAL_CHECKS )
  1480.     ASSERT ( IsValidInternal () );
  1481. #endif
  1482. }
  1483.  
  1484. /***********************************|****************************************/
  1485.  
  1486. TPathName::~TPathName ()
  1487. {
  1488.     InvalidateCache ();
  1489.     Deallocate ( fPacked );
  1490. }
  1491.  
  1492. /***********************************|****************************************/
  1493.  
  1494. TPathName&
  1495. TPathName::operator = ( const TPathName& that )
  1496. {
  1497.     if ( ASSERT ( this != &that ) )
  1498.     {
  1499.         Deallocate ();
  1500.         fPacked = Allocate ( that.fPacked );
  1501. #if defined ( INTERNAL_CHECKS )
  1502.         ASSERT ( IsValidInternal () );
  1503. #endif
  1504.     }
  1505.  
  1506.     return *this;
  1507. }
  1508.  
  1509. /***********************************|****************************************/
  1510.  
  1511. TPathName&
  1512. TPathName::operator = ( const PackedPathName* p )
  1513. {
  1514.     if  ( ASSERT ( IsValid ( p ) ) )
  1515.     {
  1516.         if ( ASSERT ( fPacked != p ) )
  1517.         {
  1518.             Deallocate ();
  1519.             fPacked = Allocate ( p );
  1520. #if defined ( INTERNAL_CHECKS )
  1521.             ASSERT ( IsValidInternal () );
  1522. #endif
  1523.         }
  1524.     }
  1525.  
  1526.     return *this;
  1527. }
  1528.  
  1529. /***********************************|****************************************/
  1530.  
  1531. Boolean
  1532. TPathName::SetNode ( unsigned short oneBasedIndex, const TRString& r )
  1533. {
  1534. #if defined ( INTERNAL_CHECKS )
  1535.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  1536. #endif
  1537.  
  1538.     //    Check whether this index could be valid.
  1539.     ASSERT_RETURN_ZERO (oneBasedIndex >= 1);
  1540.  
  1541.     //    You can't add a pathname item index if there isn't an index-1 item already
  1542.     ASSERT_RETURN_ZERO ( oneBasedIndex <= GetNodeCount() + 1);
  1543.     
  1544.     //    Unpack the existing path name
  1545.     unsigned short newNodeCount = (GetNodeCount() >  oneBasedIndex) ? GetNodeCount() : oneBasedIndex;
  1546.     RStringPtr* array = (RStringPtr *) AllocateArray ( fPacked );
  1547.     RStringPtr * newArray = (RStringPtr *) FAILNewPtrClear( sizeof(ConstRStringPtr) * newNodeCount);
  1548.     
  1549.     //    Copy the old pathname items over into this new items
  1550.     for (unsigned short i = 0; i < GetNodeCount(); ++i)
  1551.         newArray[i] = array[i];
  1552.     newArray[oneBasedIndex-1] = (RStringPtr) (const RString *) r;    // and replace the index-th one.
  1553.  
  1554.     //    Create a new packed path based on these new path items
  1555.     PackedPathName* newPackedPath = Allocate ( newArray, newNodeCount );
  1556.     ::DeallocatePtr( (Ptr) array );
  1557.     
  1558. #if defined ( INTERNAL_CHECKS )
  1559.     ASSERT ( MemError () == noErr );
  1560. #endif
  1561.  
  1562.     //    Dispose of the current memory used by this object
  1563.     Deallocate ();
  1564.     fPacked = newPackedPath;
  1565.  
  1566. #if defined ( INTERNAL_CHECKS )
  1567.     ASSERT_RETURN_ZERO ( IsValidInternal () ); 
  1568. #endif
  1569.     return true;
  1570. }
  1571.  
  1572. /***********************************|****************************************/
  1573.  
  1574. Boolean
  1575. TPathName::GetNode ( unsigned short oneBasedIndex, TRString& r ) const
  1576. {
  1577. #if defined ( INTERNAL_CHECKS )
  1578.     ASSERT_RETURN_ZERO ( IsValidInternal () );
  1579. #endif
  1580.     ASSERT_RETURN_ZERO ( IsValidIndex ( oneBasedIndex ) );
  1581.     ValidateCache ();
  1582.     ASSERT_RETURN_ZERO ( fCache [ oneBasedIndex ] != nil );
  1583.     r = *fCache [ oneBasedIndex - 1 ];
  1584.     return true;
  1585. }
  1586.  
  1587. /***********************************|****************************************/
  1588.  
  1589. Boolean
  1590. TPathName::operator == ( const TPathName& that ) const
  1591. {
  1592.     return ::OCEEqualPackedPathName ( fPacked, that.fPacked );
  1593. }
  1594.  
  1595. /***********************************|****************************************/
  1596.  
  1597. Boolean
  1598. TPathName::operator == ( const PackedPathName& p ) const
  1599. {
  1600.     return ::OCEEqualPackedPathName ( fPacked, &p );
  1601. }
  1602.  
  1603. /***********************************|****************************************/
  1604.  
  1605. const RString&
  1606. TPathName::operator [] ( unsigned short zeroBasedIndex ) const
  1607. {
  1608.     if ( IsValidIndex ( zeroBasedIndex + 1 ) )
  1609.     {
  1610.         ValidateCache ();
  1611.  
  1612. #if defined ( INTERNAL_CHECKS )
  1613.         if ( ASSERT ( TRString::IsValid ( fCache [ zeroBasedIndex ], kOCEGenericSensitive ) ) )
  1614. #endif
  1615.             return *fCache [ zeroBasedIndex ];
  1616.     }
  1617.  
  1618.     // if we get to here, we are obligated to return something,
  1619.     // so let’s return a bogus object (we should probably throw an exception, though…)
  1620.  
  1621.     static const TRString* gBozoString = nil;
  1622.  
  1623.     if ( !gBozoString )
  1624.         gBozoString = new TRString ( "TPathName::operator [] ( bad index )" );
  1625.  
  1626.     return *gBozoString;
  1627. }
  1628.  
  1629. /***********************************|****************************************/
  1630.  
  1631. Boolean
  1632. TPathName::Write ( TAbstractFile& f ) const
  1633. {
  1634.     unsigned short physicalSize = GetPhysicalSize ( fPacked );
  1635.     ASSERT_RETURN_ZERO ( f.Write ( physicalSize ) == noErr );
  1636.     ASSERT_RETURN_ZERO ( f.WriteDataIgnore ( fPacked, physicalSize ) == noErr );
  1637.     return true;
  1638. }
  1639.  
  1640. /***********************************|****************************************/
  1641.  
  1642. Boolean
  1643. TPathName::Read ( TAbstractFile& f )
  1644. {
  1645.     unsigned short physicalSize = 0;
  1646.     ASSERT_RETURN_ZERO ( f.Read ( physicalSize ) == noErr );
  1647.     ASSERT_RETURN_ZERO ( physicalSize >= sizeof ( ProtoPackedPathName ) );
  1648.     PackedPathName* newPaths = Allocate ( physicalSize );
  1649.     ASSERT_RETURN_ZERO ( newPaths != nil );
  1650.     ASSERT_RETURN_ZERO ( f.ReadDataIgnore ( newPaths, physicalSize ) == noErr );
  1651.     Deallocate ();
  1652.     fPacked = newPaths;
  1653.     return true;
  1654. }
  1655.  
  1656. /***********************************|****************************************/
  1657.  
  1658. ostream&
  1659. TPathName::operator >> ( ostream& s ) const
  1660. {
  1661. #if defined ( INTERNAL_CHECKS )
  1662.     ASSERT ( IsValidInternal () );
  1663. #endif
  1664.     ValidateCache ();
  1665.     unsigned short nodes = GetNodeCount ();
  1666.  
  1667.     for ( unsigned short index = 0; index < nodes; index++ )
  1668.     {
  1669.         if ( index > 0 )
  1670.             s << ":";
  1671.  
  1672.         s << operator [] ( index );
  1673.     }
  1674.  
  1675.     return s;
  1676. }
  1677.  
  1678.